package main

import "fmt"

/**
1 结构体类型是值类型，在方法调用中，遵守值类型的传递机制，是值拷贝传递方式
2 如希望在方法中，要改结构体变量的值，可以通过结构体指针的方式来处理

3 方法的访问范围控制的规则，和函数一样。方法名首字母小写，只能在本包访问，方法首字母大写，可以在本包和其它包访问。
4 如果一个类型实现了String()这个方法，fmt.Println(&per)会自动调用这个变量的String()
*/

type User struct {
	Age  int
	Name string
}

// 初始化时自动执行String方法
func (u *User) String() {
	fmt.Println("String方法执行了")
}

func (u User) getAge() int {
	return u.Age
}

// 给User结构体添加方法
func (u User) SetAge1(age int) {
	u.Age = age
	fmt.Println("SetAge1方法执行了")
}

// 给User结构体添加方法
func (u *User) SetAge(age int) {
	u.Age = age
	fmt.Println("SetAge方法执行了")
}

func main() {

	user := User{19, "张三"}
	fmt.Println(&user)
}

func testUser() {
	user := User{19, "张三"}
	fmt.Println(&user)
	user.SetAge(18)
	fmt.Println(user)

	age := user.getAge()
	fmt.Println("age:", age)
}

func testPerson() {
	per := Person{19, "李四"}
	fmt.Println(&per)
	fmt.Printf("%#v \n", per)
	fmt.Printf("%+v \n", per)
	per.show()
}

//--------------------
type Person struct {
	Age  int
	Name string
}

func (p *Person) String() string {
	str := fmt.Sprintf("Name:%s, Age:%d", p.Name, p.Age)
	return str
}

func (p Person) show() {
	fmt.Println("show方法执行了")
}
